from sanic import Sanic
from util.main import log_config, check_sign, dict_value
from config import app_config
from sanic import Blueprint, HTTPResponse
from sanic.exceptions import Forbidden
from tortoise.contrib.sanic import register_tortoise
from exceptions.ssp_code import SspCodeException
from sanic.response import json

from routes.main import main_route

app = Sanic("stock_chart", log_config=log_config)
app.config.FORWARDED_SECRET = "47ad7d12sdfc438b5"  # 反向代理配置
app.update_config(app_config)  # 加载配置

# 连接 mysql
register_tortoise(app, db_url=app_config["DATABASE_URI"], modules={"models": ["models"]})


# 拦截统一错误响应
@app.exception(SspCodeException)
async def bad_request(request, exception: SspCodeException):
    return json(exception.as_dict())


# 跨域 options 处理
@app.middleware("request")
def cors_middle_req(request):
    """
        路由需要启用OPTIONS方法
        前端请求后台时先发送options预检请求(浏览器机制自动发送不带传参)
    """
    if request.method.lower() == 'options':
        headers = {
            'Access-Control-Allow-Methods': "GET, OPTIONS",
            'Access-Control-Allow-Headers': "*",
            "Access-Control-Allow-Origin": "*"
        }
        return HTTPResponse('', headers=headers)


# 为需要鉴权的API添加鉴权
@app.middleware("request")
async def auth(request):
    if request.path != "/api/system_monitor" and request.args.get(
            "beb68469") != "A19EA622182C63DDC19BB22CDE982B82":
        if not check_sign(dict_value(request.headers, 'timestamp'),
                          dict_value(request.headers, 'sign')):
            raise Forbidden("拒绝访问")


# 返回中间件，增加跨域设置
@app.middleware("response")
async def access_cross(request, response):
    o = request.headers.get("origin")
    if not o:
        o = "*"
    response.headers.update({
        'Access-Control-Allow-Methods': "GET, OPTIONS",
        'Access-Control-Allow-Headers': "*",
        "Access-Control-Allow-Origin": o
    })


# 注册路由
home_group = Blueprint.group(main_route)
app.blueprint([home_group], url_prefix="/api")

if __name__ == "__main__":
    app.run(debug=app.config["DEBUG"],
            access_log=app.config["DEBUG"],
            auto_reload=app.config["DEBUG"],
            port=app.config["PORT"],
            host="0.0.0.0")
